package com.a918.controller;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.a918.dao.OrgdailyMapper;
import com.a918.entity.*;
import com.a918.service.EvaluateService;
import com.a918.service.ImportDataService;
import com.a918.util.ParamUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Component
@Controller
public class ImportDataController {
    static String loginAccessToken;

    // 从配置文件中读取数据接口url
    @Value("${url.import}")
    private String ENV_URL;

    private OrgdailyMapper orgdailyMapper;
    private ImportDataService importDataService;
    private EvaluateService evaluateService;

    @Autowired
    public ImportDataController(ImportDataService importDataService, EvaluateService evaluateService, OrgdailyMapper orgdailyMapper) {
        this.importDataService = importDataService;
        this.evaluateService = evaluateService;
        this.orgdailyMapper = orgdailyMapper;
    }


    public void openAPILogin() {
        String URL = ENV_URL + "/portal/login/client/token";

        JSONObject bizContent = JSONUtil.createObj();
        bizContent.set("clientId", ParamUtil.CLIENT_ID);
        bizContent.set("appId", ParamUtil.APP_ID);

        String result = ParamUtil.executePostRequest(URL, bizContent);
        //System.out.println(result);
        //字符串和对象间转换工具类
        JSONObject jsonObject = JSONUtil.parseObj(result);
        JSONObject jsonObject1 = (JSONObject)jsonObject.get("data");
        String access_token = (String)jsonObject1.get("access_token");
        System.out.println("access_token:" + access_token);
        ParamUtil.loginAccessToken = access_token;
    }


    public int importOrgMonthHelper(JSONObject bizContent) {
        String URL = ENV_URL + "/openapi/statistics/org/month";
        // 发送请求并解析json
        String result = ParamUtil.executePostRequestWithToken(URL, bizContent);
        JSONObject jsonObject = JSONUtil.parseObj(result);

        int code = (int)jsonObject.get("code");
        if (code != 0) {
            return -1;
        }

        // System.out.println(JSONUtil.parseObj(jsonObject.get("data")).get("records"));
        List<JSONObject> records = JSONUtil.toList((JSONArray) JSONUtil.parseObj(jsonObject.get("data")).get("records"), JSONObject.class);
        for(int i = 0; i < 10; ++i) {
            String platCode = (String)records.get(i).get("platCode");
            if (platCode.equals("YJT")) {
                // 读每页数据并写入数据库
                Orgmonth orgmonth = JSONUtil.toBean(records.get(i), Orgmonth.class);
                orgmonth.setAverageAge(orgmonth.getAverageAge());
                //省份
                String shengfen = (String) records.get(i).get("province");
                if (shengfen.equals("内蒙古自治区") || shengfen.equals("黑龙江省")) shengfen = shengfen.substring(0, 3);
                else if (!shengfen.equals("")) shengfen = shengfen.substring(0, 2);
                orgmonth.setShengfen(shengfen);
                //月份
                orgmonth.setYuefen(records.get(i).get("businessDate").toString().substring(0, 7));
                //平均工作时长
                orgmonth.setAvgWorkLength((Double) records.get(i).get("averageWorkLength"));
                //月实际派送单量
                orgmonth.setDeliveryCountMonth(Integer.valueOf((String) records.get(i).get("waybillCountSum")));

                // 数据清理
                if (orgmonth.getAverageAge() <= 1.0 || orgmonth.getAvgWorkLength() < 110 ||
                    orgmonth.getDeliveryCount() < 3 || orgmonth.getDeliveryCountMonth() < 30000) {
                    continue;
                }

                //网点月总当日完成全链量（有效单量）
                orgmonth.setWaybillNoCount(Integer.valueOf((String) records.get(i).get("currentDayValidWaybillCount")));
                //工作负荷
                orgmonth.setWorkload((Double) records.get(i).get("averageWorkLength") / ParamUtil.BASE_WORK_LENGTH * 100);
                //劳动生产率
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.MONTH, 0);
                int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); // 月天数
                orgmonth.setLaborProductivity(Double.parseDouble((String) records.get(i).get("waybillCountSum")) / days / orgmonth.getDeliveryCount());
                //人员利用率
                double avgDelivery = 0;
                List<Orgdaily> orgdailies = orgdailyMapper.getByNameAndDateRange((String) records.get(i).get("orgCode"), records.get(i).get("businessDate").toString().substring(0, 7) + "-01", records.get(i).get("businessDate").toString().substring(0, 7) + "-" + days);
                if (orgdailies.size() != 0) {
                    for (Orgdaily orgdaily : orgdailies) {
                        avgDelivery = avgDelivery + orgdaily.getDeliveryCount();
                    }
                    avgDelivery = avgDelivery / orgdailies.size();
                }
                double del_rate = avgDelivery / Double.parseDouble((String) records.get(i).get("deliveryCount")) * 100;
                if (del_rate > 100) del_rate = 100.0;
                orgmonth.setDeliveryRate(del_rate);
                //当日派件率
                orgmonth.setAvgDeliveryCountRate(Double.parseDouble((String) records.get(i).get("currentDayValidWaybillCount")) / Double.parseDouble((String) records.get(i).get("waybillCountActualSum")) * 100);

                // 网点规模类型
                if (orgmonth.getDeliveryCountMonth() >= 30000 && orgmonth.getDeliveryCountMonth() < 300000) {
                    orgmonth.setType("小规模");
                } else if (orgmonth.getDeliveryCountMonth() >= 300000 && orgmonth.getDeliveryCountMonth() < 600000) {
                    orgmonth.setType("中规模");
                } else if (orgmonth.getDeliveryCountMonth() >= 600000 && orgmonth.getDeliveryCountMonth() < 1000000) {
                    orgmonth.setType("大规模");
                } else if (orgmonth.getDeliveryCountMonth() >= 1000000) {
                    orgmonth.setType("超大规模");
                }
                importDataService.insertOrgMonth(orgmonth);
            }
        }
        return 0;
    }


    public int importOrgDailyHelper(JSONObject bizContent) {
        String URL = ENV_URL + "/openapi/statistics/org/daily";
        // 发送请求并解析json
        String result = ParamUtil.executePostRequestWithToken(URL, bizContent);
        JSONObject jsonObject = JSONUtil.parseObj(result);

        int code = (int)jsonObject.get("code");
        if (code != 0) {
            return -1;
        }
        // System.out.println(JSONUtil.parseObj(jsonObject.get("data")).get("records"));
        List<JSONObject> records = JSONUtil.toList((JSONArray) JSONUtil.parseObj(jsonObject.get("data")).get("records"), JSONObject.class);
        for(int i = 0; i < 10; ++i) {
            String platCode = (String)records.get(i).get("platCode");
            if (platCode.equals("YJT")) {
                Orgdaily orgdaily = JSONUtil.toBean(records.get(i), Orgdaily.class);
                //workLength
                try {
                    orgdaily.setWorkLength((Double) records.get(i).get("averageWorkLength"));
                } catch (ClassCastException e) {
                    // averageWorkLength咋还有Integer？ 11小时整的还有
                    orgdaily.setWorkLength(Double.valueOf(records.get(i).get("averageWorkLength").toString()));
                }

                //日全链量
                orgdaily.setWaybillCount(Integer.parseInt((String) records.get(i).get("currentDayValidWaybillCount")));
                //月实际派单量
                orgdaily.setDeliveryCountOfDay(Integer.parseInt((String) records.get(i).get("waybillCountActualSum")));
                orgdaily.setDeliveryCountRate(new Double((Double.valueOf((records.get(i).get("deliveryCountRate")).toString()) * 10000.0)).intValue());
                importDataService.insertOrgDaily(orgdaily);
            }
        }
        return 0;
    }


    public int importDlvyDailyHelper(JSONObject bizContent) {
        String URL = ENV_URL + "/openapi/statistics/delivery/daily";
        // 发送请求并解析json
        String result = ParamUtil.executePostRequestWithToken(URL, bizContent);
        JSONObject jsonObject = JSONUtil.parseObj(result);

        int code = (int)jsonObject.get("code");
        if (code != 0) {
            return -1;
        }
        // System.out.println(JSONUtil.parseObj(jsonObject.get("data")).get("records"));
        List<JSONObject> records = JSONUtil.toList((JSONArray) JSONUtil.parseObj(jsonObject.get("data")).get("records"), JSONObject.class);
        List<Dlvydaily> dlvydailyList = new ArrayList<>();
        for(int i = 0; i < 100; ++i) {
            String platCode = (String)records.get(i).get("platCode");
            if (platCode.equals("YJT")) {
                Dlvydaily dlvydaily = JSONUtil.toBean(records.get(i), Dlvydaily.class);
                dlvydailyList.add(dlvydaily);
            }
        }
        importDataService.insertDlvyDaily(dlvydailyList);
        return 0;
    }


    public int importDlvyMonthHelper(JSONObject bizContent) {
        String URL = ENV_URL + "/openapi/statistics/delivery/month";
        // 发送请求并解析json
        String result = ParamUtil.executePostRequestWithToken(URL, bizContent);
        JSONObject jsonObject = JSONUtil.parseObj(result);

        int code = (int)jsonObject.get("code");
        if (code != 0) {
            return -1;
        }
        // System.out.println(JSONUtil.parseObj(jsonObject.get("data")).get("records"));
        List<JSONObject> records = JSONUtil.toList((JSONArray) JSONUtil.parseObj(jsonObject.get("data")).get("records"), JSONObject.class);
        for(int i = 0; i < 10; ++i) {
            String platCode = (String)records.get(i).get("platCode");
            if (platCode.equals("YJT")) {
                Dlvymonth dlvymonth = JSONUtil.toBean(records.get(i), Dlvymonth.class);
                importDataService.insertDlvyMonth(dlvymonth);
            }
        }
        return 0;
    }


    //每月1号5点30执行
    @Scheduled(cron = "0 30 5 1 * ?")
    @PostMapping("/importOrgMonth")
    @ResponseBody
    public Map<String,Object> importOrgMonth() {
        openAPILogin();

        // 第一次请求获取total数目
        String URL = ENV_URL + "/openapi/statistics/org/month";
        int limit = 10;
        JSONObject bizContent = JSONUtil.createObj();

        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth = localDate.minusMonths(1);
        String year = Integer.toString(lastMonth.getYear());
        int month = lastMonth.getMonthValue();
        String monthStr;
        if(month < 10){
            monthStr = "0"+ month;
        }
        else{
            monthStr = Integer.toString(month);
        }
        String yuefen0 = year+"-"+monthStr;
        bizContent.set("startDate", yuefen0 + "-01");
        bizContent.set("endDate", yuefen0 + "-28");
        bizContent.set("page", "1");
        bizContent.set("limit", Integer.toString(limit));

        Map<String,Object> res1 = new HashMap<>();

        // 发送请求并解析json
        String result = ParamUtil.executePostRequestWithToken(URL, bizContent);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        System.out.println(result);
        int code = (int)jsonObject.get("code");
        if (code != 0) {
            // TODO: 错误处理 记录日志
            res1.put("msg", "error");
            return res1;
        }
        int total = Integer.parseInt((String)JSONUtil.parseObj(jsonObject.get("data")).get("total"));

        // 依次获取每页的数据并存到数据库
        for (int page = 0; page < total / limit; page++) {
            bizContent.set("page", Integer.toString(page));
            int res = importOrgMonthHelper(bizContent);
            if (res != 0) {
                res1.put("msg", "error");
                return res1;
            }
        }

        // 接收完一个月的数据计算一次熵权法
        if (total > 0) {
            double[] W = evaluateService.addshangquanF(yuefen0.substring(0,7));
            Weight weight = new Weight();
            weight.setYuefen(yuefen0.substring(0,7));
            weight.setDailymaxwaybillcount(W[0]);
            weight.setAverageage(W[1]);
            weight.setWaybillnocount(W[2]);
            weight.setAvgdeliverycountrate(W[3]);
            weight.setDeliveryrate(W[4]);
            weight.setWorkload(W[5]);
            List<String> yuefenList = importDataService.checkyuefen();
            if(!yuefenList.contains(yuefen0)){
                importDataService.insertWeight(weight);
            }else {
                importDataService.updateByYuefen(weight);
            }
        }

        List<String> wangdians = evaluateService.getAllOrgCodeByYuefen(yuefen0);
        for (String wangdian:wangdians){
            evaluateService.addinc_coef(wangdian,yuefen0);
        }
        importDataService.rankByYuefen(yuefen0);
        importDataService.updateRank(yuefen0);

        res1.put("msg","success");
        Date now = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");//可以方便地修改日期格式
        String time = dateFormat.format(now);
        System.out.println(time);
        System.out.println("网点月数据导入成功！");
        return res1;
    }


    //每天5点30执行
    @Scheduled(cron = "0 30 5 * * ?")
    @PostMapping("/importOrgDaily")
    @ResponseBody
    public Map<String,Object> importOrgDaily() {
        openAPILogin();

        // 第一次请求获取total数目
        String URL = ENV_URL + "/openapi/statistics/org/daily";
        int limit = 10;
        JSONObject bizContent = JSONUtil.createObj();
        LocalDate localDate = LocalDate.now();
        LocalDate yesterday = localDate.plusDays(-1);
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String yesterdayStr = yesterday.format(fmt);

        System.out.println(yesterdayStr);

        bizContent.set("startDate", yesterdayStr);
        bizContent.set("endDate", yesterdayStr);
        bizContent.set("page", "1");
        bizContent.set("limit", Integer.toString(limit));
        Map<String,Object> res1 = new HashMap<>();

        // 发送请求并解析json
        String result = ParamUtil.executePostRequestWithToken(URL, bizContent);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        System.out.println(result);
        int code = (int) jsonObject.get("code");
        if (code != 0) {
            // TODO: 错误处理 记录日志
            res1.put("msg","error");
            return res1;
        }
        int total = Integer.parseInt((String) JSONUtil.parseObj(jsonObject.get("data")).get("total"));

        // 依次获取每页的数据并存到数据库
        for (int page = 0; page < total / limit; page++) {
            bizContent.set("page", Integer.toString(page));
            int res = importOrgDailyHelper(bizContent);
            if (res != 0) {
                res1.put("msg","error");
                return res1;
            }

        }
        res1.put("msg","success");
        System.out.println("网点日数据导入成功！");
        return res1;
    }


    //每天5点30执行
    @Scheduled(cron = "0 30 5 * * ?")
    @PostMapping("/importDlvyDaily")
    @ResponseBody
    public Map<String,Object> importDlvyDaily() {
        openAPILogin();
        // 第一次请求获取total数目
        String URL = ENV_URL + "/openapi/statistics/delivery/daily";
        int limit = 100;
        JSONObject bizContent = JSONUtil.createObj();
        LocalDate localDate = LocalDate.now();
        LocalDate yesterday = localDate.plusDays(-1);
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String yesterdayStr = yesterday.format(fmt);

        System.out.println(yesterdayStr);

        bizContent.set("startDate", yesterdayStr);
        bizContent.set("endDate", yesterdayStr);
        bizContent.set("page", "1");
        bizContent.set("limit", Integer.toString(limit));

        Map<String,Object> res1 = new HashMap<>();

        // 发送请求并解析json
        String result = ParamUtil.executePostRequestWithToken(URL, bizContent);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        System.out.println(result);
        int code = (int) jsonObject.get("code");
        if (code != 0) {
            // TODO: 错误处理 记录日志
            res1.put("msg","error");
            return res1;
        }
        int total = Integer.parseInt((String) JSONUtil.parseObj(jsonObject.get("data")).get("total"));

        // 依次获取每页的数据并存到数据库
        for (int page = 0; page < total / limit; page++) {
            bizContent.set("page", Integer.toString(page));
            int res = importDlvyDailyHelper(bizContent);
            if (res != 0) {
                res1.put("msg","error");
                return res1;
            }

        }

        res1.put("msg","success");
        System.out.println("快递员日数据导入成功！");
        return res1;
    }


    //每月1号执行5点30执行
    @Scheduled(cron = "0 30 5 1 * ?")
    @PostMapping("/importDlvyMonth")
    @ResponseBody
    public Map<String,Object> importDlvyMonth() {
        openAPILogin();

        // 第一次请求获取total数目
        String URL = ENV_URL + "/openapi/statistics/delivery/month";
        int limit = 10;
        JSONObject bizContent = JSONUtil.createObj();

        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth = localDate.minusMonths(1);
        String year = Integer.toString(lastMonth.getYear());
        int month = lastMonth.getMonthValue();
        String monthStr;
        if(month < 10){
            monthStr = "0"+ month;
        }
        else{
            monthStr = Integer.toString(month);
        }
        String yuefen1 = year+"-"+monthStr;
        bizContent.set("startDate", yuefen1 + "-01");
        bizContent.set("endDate", yuefen1 + "-28");
        bizContent.set("page", "1");
        bizContent.set("limit", Integer.toString(limit));

        Map<String,Object> res1 = new HashMap<>();

        // 发送请求并解析json
        String result = ParamUtil.executePostRequestWithToken(URL, bizContent);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        System.out.println(result);
        int code = (int) jsonObject.get("code");
        if (code != 0) {
            // TODO: 错误处理 记录日志
            res1.put("msg","error");
            return res1;
        }
        int total = Integer.parseInt((String) JSONUtil.parseObj(jsonObject.get("data")).get("total"));

        // 依次获取每页的数据并存到数据库
        for (int page = 0; page < total / limit; page++) {
            bizContent.set("page", Integer.toString(page));
            int res = importDlvyMonthHelper(bizContent);
            if (res != 0) {
                res1.put("msg","error");
                return res1;
            }

        }
        res1.put("msg","success");
        System.out.println("快递员月数据导入成功！");
        return res1;
    }


//    @GetMapping("/importData")
//    public String importDataPage(){
//        return "back/ImportData";
//    }
}
